package com.example.demo.DateTest.util;

import org.apache.commons.lang3.ObjectUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 功能描述：
 *
 * @author Administrator
 * @version 1.0
 * @Date Jul 19, 2008
 * @Time 9:47:53 AM
 */
public class DateUtil {

    public static Date date = null;

    public static DateFormat dateFormat = null;

    public static Calendar calendar = null;

    public enum DateSort {

        YEAR("y", 1), QUARTER("q", 2), MONTH("m", 3), WEEK("w", 4), DAY("d", 5), HOUR("h", 6), MINUTE("n", 7), SECOND("s", 8);

        private String name;
        private int index;

        DateSort(String name, int index) {
            this.name = name;
            this.index = index;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }
    }

    public static boolean isDate(String dateString) {
        /****************************************
         *判断字符串是否是日期的函数,字符串形如yyyy-mm-dd hh:mi:ss
         *返回true则是日期
         *返回false则不是日期
         *****************************************/
        String[] newdate;
        String[] newhour;

        String[] oldstr = dateString.split(" ");
        try {
            if (oldstr.length == 1)
            //传入的字符串是不带时间的日期
            {
                newdate = dateString.split("-");
                int year = Integer.parseInt(newdate[0]);
                int month = Integer.parseInt(newdate[1]) - 1;
                int day = Integer.parseInt(newdate[2]);

                if (month > 11 || month < 0) {
                    return false;
                }
                if (((month % 2) != 0) && ((month > 6 && (day > 31 || day < 1)) || (month <= 6 && (day > 30 || day < 1)))) {
                    return false;
                }
                if (((month % 2) == 0) && ((month > 6 && (day > 30 || day < 1)) || (month <= 6 && (day > 31 || day < 1)))) {
                    return false;
                }
                if (leapYear(year) && month == 1 && day > 29) {
                    return false;
                }
                if (!leapYear(year) && month == 1 && day > 28) {
                    return false;
                }
            } else {
                //传入的字符串是带时间的日期
                String newdate1, newhour1;
                newdate1 = oldstr[0];
                newhour1 = oldstr[1];
                newdate = newdate1.split("-");
                newhour = newhour1.split(":");
                int year = Integer.parseInt(newdate[0]);
                int month = Integer.parseInt(newdate[1]) - 1;
                int day = Integer.parseInt(newdate[2]);
                int hour = Integer.parseInt(newhour[0]);
                int min = Integer.parseInt(newhour[1]);
                int sec = Integer.parseInt(newhour[2]);
                if (month > 11 || month < 0) {
                    return false;
                }
                if (((month % 2) != 0) && ((month > 6 && (day > 31 || day < 1)) || (month <= 6 && (day > 30 || day < 1)))) {
                    return false;
                }
                if (((month % 2) == 0) && ((month > 6 && (day > 30 || day < 1)) || (month <= 6 && (day > 31 || day < 1)))) {
                    return false;
                }
                if ((leapYear(year) == true) && (month == 1) && (day > 29 || day < 1)) {
                    return false;
                }
                if ((leapYear(year) == false) && (month == 1) && (day > 28 || day < 1)) {
                    return false;
                }
                if ((hour > 23 || hour < 0) || (min > 59 || min < 0) || (sec > 59 || sec < 0)) {
                    return false;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 功能描述：格式化日期
     *
     * @param dateStr String 字符型日期
     * @param format  String 格式
     * @return Date 日期
     */
    public static Date parseDate(String dateStr, String format) {
        try {
            dateFormat = new SimpleDateFormat(format);
            date = dateFormat.parse(dateStr);
        } catch (Exception ignored) {
        }
        return date;
    }

    /**
     * 格式化日期
     *
     * @param date   时间类型时间
     * @param format 指定格式
     * @return Date
     */
    public static Date toDate(Date date, String format) {
        try {
            if (date != null) {
                dateFormat = new SimpleDateFormat(format);
                String dateStr = dateFormat.format(date);
                date = dateFormat.parse(dateStr);
            }
        } catch (Exception ignored) {
        }
        return date;
    }

    /**
     * 功能描述：格式化日期
     *
     * @param dateStr String 字符型日期：YYYY-MM-DD 格式
     * @return Date
     */
    public static Date parseDate(String dateStr) {
        return parseDate(dateStr, "yyyy-MM-dd");
    }

    /**
     * 功能描述：格式化输出日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return 返回字符型日期
     */
    public static String format(Date date, String format) {
        String result = "";
        try {
            if (date != null) {
                dateFormat = new SimpleDateFormat(format);
                result = dateFormat.format(date);
            }
        } catch (Exception ignored) {
        }
        return result;
    }

    /**
     * 功能描述：
     *
     * @param date Date 日期
     * @return
     */
    public static String format(Date date) {
        return format(date, "yyyy-MM-dd");
    }

    /**
     * 功能描述：返回年份
     *
     * @param date Date 日期
     * @return 返回年份
     */
    public static int getYear(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 功能描述：返回当前年份
     *
     * @return 返回年份
     */
    public static int getYear() {
        return getYear(new Date());
    }

    /**
     * 功能描述：返回月份
     *
     * @param date Date 日期
     * @return 返回月份
     */
    public static int getMonth(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 功能描述：返回月份
     *
     * @return 返回月份
     */
    public static int getMonth() {
        return getMonth(new Date());
    }


    /********************************
     *传入日期
     *得到星期
     ********************************/
    public static int getWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK) - 1;
    }


    /********************************
     *传入日期
     *得到星期
     ********************************/
    public static int getWeek() {
        return getWeek(new Date());
    }


    /********************************
     *传入日期
     *得到中文星期的函数
     ********************************/
    public static String getChineseWeek(Date date) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    /********************************
     *得到中文星期的函数
     ********************************/
    public static String getChineseWeek() {

        return getChineseWeek(new Date());
    }

    /**
     * 功能描述：返回日份
     *
     * @param date Date 日期
     * @return 返回日份
     */
    public static int getDay(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 功能描述：返回日份
     *
     * @return 返回日份
     */
    public static int getDay() {
        return getDay(new Date());
    }

    /**
     * 功能描述：返回小时
     *
     * @param date 日期
     * @return 返回小时
     */
    public static int getHour(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述：返回小时
     *
     * @return 返回小时
     */
    public static int getHour() {
        return getHour(new Date());
    }

    /**
     * 功能描述：返回分钟
     *
     * @param date 日期
     * @return 返回分钟
     */
    public static int getMinute(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 功能描述：返回分钟
     *
     * @return 返回分钟
     */
    public static int getMinute() {
        return getMinute(new Date());
    }

    /**
     * 返回秒钟
     *
     * @param date Date 日期
     * @return 返回秒钟
     */
    public static int getSecond(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 返回秒钟
     *
     * @return 返回秒钟
     */
    public static int getSecond() {
        return getSecond(new Date());
    }

    /**
     * 功能描述：返回毫秒
     *
     * @param date 日期
     * @return 返回毫秒
     */
    public static long getMillis(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getTimeInMillis();
    }

    /**
     * 功能描述：返回毫秒
     *
     * @return 返回毫秒
     */
    public static long getMillis() {
        return getMillis(new Date());
    }

    /**
     * 功能描述：返回该月有多少天
     *
     * @param date 日期
     * @return 返回毫秒
     */
    public static int getDayOfMonth(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int day = calendar.getActualMaximum(Calendar.DATE);
        return day;
    }

    /**
     * 功能描述：返回字符型日期
     *
     * @param date 日期
     * @return 返回字符型日期 yyyy-MM-dd 格式
     */
    public static String getDate(Date date) {
        return format(date, "yyyy-MM-dd");
    }

    /**
     * 功能描述：返回字符型时间
     *
     * @param date Date 日期
     * @return 返回字符型时间 HH:mm:ss 格式
     */
    public static String getTime(Date date) {
        return format(date, "HH:mm:ss");
    }

    /**
     * 功能描述：返回字符型日期时间
     *
     * @param date Date 日期
     * @return 返回字符型日期时间 yyyy/MM/dd HH:mm:ss 格式
     */
    public static String getDateTime(Date date) {
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }


    /****************************************************************************
     *日期加减操作函数
     *如果传入的date不是正确的日期将返回原值，
     *参数number如果是正数则是在原来的日期上加
     *参数number如果是负数则是在原来的日期上减
     *参数flag是标识是否返回有时间的日期，true返回有时间的日期否则只是日期
     *参数date可以是带时间和不带时间的日期格式的字符串，也可以是日期
     *如果date是不带时间的字符串，而且参数interval的值是h或m或s，将不能实现日期加减
     *参数interval设置的值为如下时代表的意义，否则返回原值
     *y 代表 年加减
     *q 代表 季加减
     *m 代表 月加减
     *w 代表 周加减
     *d 代表 日加减
     *h 代表 时加减
     *n 代表 分加减
     *s 代表 秒加减
     **************************************************************************/
    public static Date dateAdd(String interval, int number, Date date) {
        //System.out.println("1="+DateUtil.format(date));
        int year = getYear(date);
        int month = getMonth(date) - 1;
        int day = getDay(date);
        int hour = getHour(date);
        int min = getMinute(date);
        int sec = getSecond(date);

        if ("y".equals(interval)) {
            year += number;
        }
        if ("q".equals(interval)) {
            month += number * 3;
        }
        if ("m".equals(interval)) {
            month += number;
        }
        if ("w".equals(interval)) {
            day += number * 7;
        }
        if ("d".equals(interval)) {
            day += number;
        }
        if ("h".equals(interval)) {
            hour += number;
        }
        if ("n".equals(interval)) {
            min += number;
        }
        if ("s".equals(interval)) {
            sec += number;
        }
        //System.out.println("2="+year+"-"+month+"-"+day);
        Calendar calendar = new GregorianCalendar();
        calendar.set(year, month, day, hour, min, sec);

        return calendar.getTime();
    }


    /**
     * 功能描述：日期相加
     *
     * @param date Date 日期
     * @param day  int 天数
     * @return 返回相加后的日期
     */
    public static Date addDate(Date date, int day) {
        calendar = Calendar.getInstance();
        long millis = getMillis(date) + ((long) day) * 24 * 3600 * 1000;
        calendar.setTimeInMillis(millis);
        return calendar.getTime();
    }

    /**
     * 功能描述：日期相减
     *
     * @param date  Date 日期
     * @param date1 Date 日期
     * @return 返回相减后的日期
     */
    public static int diffDate(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
    }

    public static int Quarter(Date date) {
        //返回季度
        if (getMonth(date) < 4) {
            return 1;
        }
        if (getMonth(date) < 7 && getMonth(date) > 3) {
            return 2;
        }
        if (getMonth(date) < 10 && getMonth(date) > 6) {
            return 3;
        }
        if (getMonth(date) < 13 && getMonth(date) > 9) {
            return 4;
        }
        return -1;
    }

    public static boolean leapYear(int year) {
        /*********************************
         *判断是否是润年的函数
         *返回true则是润年
         *返回false则不是润年
         **********************************/
        return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
    }

    public static int dayOfYear(Date date) {
        //得到当前日期是这年的第几天
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_YEAR);
    }

    @SuppressWarnings("unused")
    public static long dateDiff(String interval, Date date1, Date date2) {
        /*****************************************************************************
         *得到两日期差值的函数
         *参数date可以是带时间和不带时间的日期格式的字符串，也可以是日期，返回值是date1-date2的整数
         *如果date是不带时间的字符串，而且参数interval的值是h或m或s，将不能实现日期的差值
         *参数interval设置的值为如下时代表的意义，否则返回-1
         *y 代表 date1和date2相差的年数
         *q 代表 date1和date2相差的季数
         *m 代表 date1和date2相差的月数
         *w 代表 date1和date2相差的周数
         *d 代表 date1和date2相差的日数
         *h 代表 date1和date2相差的时数
         *n 代表 date1和date2相差的分数
         *s 代表 date1和date2相差的秒数
         *出错返回-1
         *****************************************************************************/
        long diffInMillis = date1.getTime() - date2.getTime(); // 毫秒差

        switch (interval.toLowerCase()) {
            case "y":  // 年
                return (long) (diffInMillis / (1000L * 60 * 60 * 24 * 365));
            case "q":  // 季度
                return (long) (diffInMillis / (1000L * 60 * 60 * 24 * 91));
            case "m":  // 月
                return (long) (diffInMillis / (1000L * 60 * 60 * 24 * 30));
            case "d":  // 天
                return (long) (diffInMillis / (1000L * 60 * 60 * 24));
            case "h":  // 小时
                return (long) (diffInMillis / (1000L * 60 * 60));
            case "n":  // 分钟
                return (long) (diffInMillis / (1000L * 60));
            case "s":  // 秒
                return (long) (diffInMillis / 1000L);
            default:
                return -1L;
        }
    }

    public static long dateDiff(String interval, String dateString1, String dateString2) {
        /*****************************************************************************
         *得到两日期差值的函数
         *参数date传入的值不是正确的日期将返回原值，
         *参数date可以是带时间和不带时间的日期格式的字符串，也可以是日期，返回值是date1-date2的整数
         *如果date是不带时间的字符串，而且参数interval的值是h或m或s，将不能实现日期的差值
         *参数interval设置的值为如下时代表的意义，否则返回-1
         *y 代表 dateString1和dateString2相差的年数
         *q 代表 dateString1和dateString2相差的季数
         *m 代表 dateString1和dateString2相差的月数
         *w 代表 dateString1和dateString2相差的周数
         *d 代表 dateString1和dateString2相差的日数
         *h 代表 dateString1和dateString2相差的时数
         *n 代表 dateString1和dateString2相差的分数
         *s 代表 dateString1和dateString2相差的秒数
         *出错返回-1
         ******************************************************************************/
        if (!isDate(dateString1) || !isDate(dateString2)) {
            return -1;
        }
        Date dt1 = ObjectUtils.isEmpty(parseDate(dateString1,"yyyy-MM-dd HH:mm:ss"))?parseDate(dateString1,"yyyy-MM-dd"):parseDate(dateString1,"yyyy-MM-dd HH:mm:ss");
        Date dt2 = ObjectUtils.isEmpty(parseDate(dateString2,"yyyy-MM-dd HH:mm:ss"))?parseDate(dateString1,"yyyy-MM-dd"):parseDate(dateString1,"yyyy-MM-dd HH:mm:ss");
        return dateDiff(interval, dt1, dt2);
    }

    /**
     * 功能描述：取得指定时间所在月份的第一天
     *
     * @param strdate String 字符型日期 格式:yyyy-MM-dd
     * @return String yyyy-MM-dd 格式
     */
    public static String getMonthBegin(String strdate) {
        date = parseDate(strdate, "yyyy-MM-dd");
        return format(date, "yyyy-MM") + "-01";
    }

    /**
     * 功能描述：取得指定时间所在年份的第一天
     *
     * @param strdate String 字符型日期 格式:yyyy-MM-dd
     * @return String yyyy-MM-dd 格式
     */
    public static String getYearBegin(String strdate) {
        date = parseDate(strdate, "yyyy-MM-dd");
        return format(date, "yyyy") + "-01-01";
    }

    /**
     * 功能描述：取得指定年份指定月份的第一天的字符串类型
     *
     * @param year 年
     * @param month 月
     * @return String yyyy-MM-dd 格式
     */
    public static String getMonthBeginToString(int year, int month) {
        date = parseDate(year + "-" + month + "-01", "yyyy-MM-dd");
        return format(date, "yyyy-MM-dd");
    }

    /**
     * 功能描述：取得指定年份指定月份的第一天的时间类型
     *
     * @param year 年
     * @param month 月
     * @return String yyyy-MM-dd 格式
     */
    public static Date getMonthBeginToDate(int year, int month) {
        date = parseDate(year + "-" + month + "-01", "yyyy-MM-dd");
        return date;
    }

    /**
     * 功能描述：取得指定月份的最后一天
     *
     * @param strdate String 字符型日期 格式:yyyy-MM-dd
     * @return String 日期字符串 yyyy-MM-dd格式
     */
    public static String getMonthEnd(String strdate) {
        date = parseDate(getMonthBegin(strdate));
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        return formatDate(calendar.getTime());
    }

    /**
     * 功能描述：常用的格式化日期
     *
     * @param date Date 日期
     * @return String 日期字符串 yyyy-MM-dd格式
     */
    public static String formatDate(Date date) {
        return formatDateByFormat(date, "yyyy-MM-dd");
    }

    /**
     * 功能描述：以指定的格式来格式化日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return String 日期字符串
     */
    public static String formatDateByFormat(Date date, String format) {
        String result = "";
        if (date != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                result = sdf.format(date);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static int getMonthSpace(String date1, String date2) throws ParseException {
        int result = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(sdf.parse(date1));
        c2.setTime(sdf.parse(date2));
        result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
        return result == 0 ? 1 : Math.abs(result);
    }

    public static int getWorkDays(String date1, String date2) {

        long day = dateDiff("d", date1, date2);
        int workDay = 0;
        for (int i = 0; i < day; i++) {

            Date date = dateAdd("d", i, parseDate(date1));
            if (getWeek(date) > 0 && getWeek(date) < 6) {
                workDay++;
            }
        }
        return workDay == 0 ? 1 : workDay;

    }

    /**
     * 获得当前系统的时间，返回sql类型
     */
    public static Timestamp getSqlDate() {
        return Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

    public static Timestamp getSqlDate(Date date) {
        return Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
    }

    /*

     *//**
     * 根据固定的格式，将字符串转化为Date
     * @param str
     * @param ftm
     * @return
     *//*
	public static Date parseDate(String str, String ftm) {
		if (str == null){
			return null;
		}
		try {
			return new SimpleDateFormat(ftm).parse(str);
		} catch (ParseException e) {
			return null;
		}

	}*/

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 转换为时间（天,时:分:秒.毫秒）
     *
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    public static String formatDateTime2(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s;
    }


    public static String formatDateTime3(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        return (day > 0 ? day + "天" : "") + ( hour > 0 ? hour + "小时" : "") + ( min > 0 ? min + "分" : "") + ( s > 0 ? s + "秒": "" );
    }

    /**
     * 获取两个日期之间的天数，Date类型
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 获取两个日期之间的天数，字符串格式
     *
     * @param before
     * @param after
     * @param fmt    : 字符串的日期格式
     * @return
     */
    public static double getDistanceOfTwoDate(String before, String after, String fmt) {
        Date beforeD = parseDate(before, fmt);
        Date afterD = parseDate(after, fmt);

        return getDistanceOfTwoDate(beforeD, afterD);
    }

    /**
     * @param before
     * @param after
     * @return
     * @Description: 获取两个日期之间的小时数
     */
    public static double getDistHoursOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60);
    }

    /**
     * @param start
     * @param end
     * @return
     * @Description: 获取两个时间相差的分钟数
     */
    public static Integer diffMinute(Date start, Date end) {
        return (int) Math.ceil((double) (end.getTime() - start.getTime()) / (1000 * 60));
    }

    /**
     * 通过毫秒时间戳获取小时数和分钟数
     *
     * @param time
     * @return
     */
    public static String getHourAndMinute(long time) {
        int minute = (int) Math.ceil((double) (time) / (1000 * 60));
        int hours = (int) Math.floor((double) minute / 60);
        minute = minute % 60;
        StringBuilder sb = new StringBuilder();
        if (hours > 0) {
            sb.append(hours).append("小时");
        }
        if (minute > 0) {
            sb.append(minute).append("分");
        }
        return sb.toString();
    }

    /**
     * 获取时间段内所有日期（包前不包后）
     *
     * @param dBegin
     * @param dEnd
     * @return
     */
    public static List<String> findDates(String dBegin, String dEnd) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date startDate = dateFormat.parse(dBegin);
            Date endDate = dateFormat.parse(dEnd);
            List<String> lDate = new ArrayList<String>();
            Calendar calBegin = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calBegin.setTime(startDate);
            Calendar calEnd = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calEnd.setTime(endDate);
            calEnd.add(Calendar.DAY_OF_MONTH, -1);
            lDate.add(dBegin);
            // 测试此日期是否在指定日期之后
            while (calEnd.getTime().after(calBegin.getTime())) {
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                lDate.add(dateFormat.format(calBegin.getTime()));
            }
            return lDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取两个日期中所有天
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param include   是否包含结束时间
     * @return List<Date> 格式 +2：[ ]、[ )
     */
    public static List<Date> betweenDayInclude(Date startTime, Date endTime, Boolean include) {
        List<Date> returnList = new ArrayList<>();

        Calendar start = Calendar.getInstance();
        start.setTime(startTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        /*
            避免出现 开始时间 为当天日出的同时 结束日间 为日落时分
            第一阶段：判断出不是同一天，是过去的天 ✓
            第二阶段：同一天进行判断 开始时间 依旧是 结束时间的前面 ✗
            总结：这是个 bug，得排除
         */
        end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH), end.get(Calendar.DATE), 0, 0, 0);

        while (start.before(end)) {
            returnList.add(start.getTime());
            start.add(Calendar.DAY_OF_YEAR, 1);
        }
        if (Boolean.TRUE.equals(include)) {
            returnList.add(end.getTime());
        }
        return returnList;
    }

    /**
     * 获取指定月份的上月指定某一天
     *
     * @param day
     * @return
     */
    public static String getPreMonthDay(String date, Integer day) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();//今天的时间
        try {
            c.setTime(dateFormat.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.add(Calendar.MONTH, -1);//时间月份-1支持1月的上月
        c.set(Calendar.DAY_OF_MONTH, day);//设置上月XX号
        String dateStr = dateFormat.format(c.getTime());
        return dateStr;
    }

    /**
     * 获取指定月份的下个月指定某一天
     *
     * @param day
     * @return
     */
    public static String getNextMonthDay(String date, Integer day) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();//今天的时间
        try {
            c.setTime(dateFormat.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.add(Calendar.MONTH, 1);//时间月份+1支持1月的上月
        c.set(Calendar.DAY_OF_MONTH, day);//设置上月XX号
        String dateStr = dateFormat.format(c.getTime());
        return dateStr;
    }

    /**
     * 判断指定参数是否为期望的格式
     *
     * @param dateStr 参数
     * @param format 期望的日期格式(例:yyyy年MM月dd日)
     * @return boolean
     */
    public static boolean isValidDateFormat(String dateStr, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false); // 设置严格匹配,禁止容忍解析错误

        try {
            sdf.parse(dateStr);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 判断传入时间为什么类型
     *
     * @param dateStr 时间参数
     * @return String
     */
    public static String detectDateFormat(String dateStr) {
        String regex = "^\\d{4}(年|-|/)\\d{1,2}(月|-|/)\\d{1,2}(日)?$";
        // 判断是否匹配汉字组合或 "-" 组合 或 "/" 组合
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(dateStr);

        if (matcher.matches()) {
            if (dateStr.contains("年")) {
                return "yyyy年MM月dd日";
            } else if (dateStr.contains("-")) {
                return "yyyy-MM-dd";
            } else if (dateStr.contains("/")) {
                return "yyyy/MM/dd";
            }
        }
        // 非日期格式或无法识别的日期格式
        return null;
    }
}
